/*
* Class: RssReaderFrame::JFrame
* Description: The main Frame of the RssReaderApp. Represents most of the 
* business part of the app and is responsible for updating the database,
* handling user input and saving and loading the database. 
*
* Note:
* Date: March 28, 2012
* Author: Shane Swayney
*/

package rssreaderapp;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;


/**
 *  Main Display Frame for RssFeedReaderApp.  
 * @author Shane Swayney <shane.swayney@gmail.com>
 */
public class RssReaderFrame extends javax.swing.JFrame implements ActionListener{

    /**
     * Constructor loads RssFeed Database, Initializes all components and updates
     * display of RssFeeds. 
     */
    public RssReaderFrame() {
        //Load RssFeeds DB
        rssFeedsDB = new RssFeedsDB();
        try {
            rssFeedsDB.loadDB();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException | ClassNotFoundException ex) {
            Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        //initialize gui components
        initComponents();
        
//        feedsDisplayList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        
        //Update and display the rssReaderListModel to display feeds in DB
        updateDisplayListModel(rssFeedsDB.getFeedsIterator()); 
        
        //Set Feeds update Timer
        updateFeedsTimer = new Timer(MINUTE * 15, this);
        
        //Set scrolling animation variables.
        scrollAnimationTimer = new Timer(10,this);
        viewport = this.FeedsScrollPane.getViewport();

    }
    
    @Override
    public void actionPerformed (ActionEvent e)
    {
        if(e.getSource().equals(scrollAnimationTimer))
        {
            Dimension size = viewport.getSize();
            Point curPnt = viewport.getViewPosition();
            int scrollBarSize = feedsDisplayList.getWidth() - viewport.getWidth();
            FeedsScrollPane.getHorizontalScrollBar().setPreferredSize(new Dimension(0,0));
            
            
            

            if((curPnt.x + 10) < scrollBarSize)
            {
                curPnt.x++;
                viewport.setViewPosition(curPnt);
            }
            else
            {
                curPnt.x = 0;
                viewport.setViewPosition(curPnt);
            }
        }
        
        if(e.getSource().equals(updateFeedsTimer))
        {
            updateRssFeeds();
        }
    }




    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        addRssMenuItem = new javax.swing.JMenuItem();
        removeRssMenuItem = new javax.swing.JMenuItem();
        updateFeedsMenuItem = new javax.swing.JMenuItem();
        windowOpacityMenu = new javax.swing.JMenu();
        fullOpacityButton = new javax.swing.JRadioButtonMenuItem();
        nintyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        eightyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        seventyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        sixtyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        fiftyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        fortyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        thirtyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        twentyPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        tenPercentOpacityButton = new javax.swing.JRadioButtonMenuItem();
        opacityRadioButtonGroup = new javax.swing.ButtonGroup();
        exitMenuItem = new javax.swing.JMenuItem();
        RssReaderPanel = new javax.swing.JPanel();
        FeedsPanel = new javax.swing.JPanel();
        FeedsScrollPane = new javax.swing.JScrollPane();
        feedsDisplayList = new javax.swing.JList<rssreaderapp.ItemComponent>();

        addRssMenuItem.setText("Add Rss Link");
        addRssMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addRssMenuItemActionPerformed(evt);
            }
        });

        removeRssMenuItem.setText("Remove Rss Link");
        removeRssMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeRssMenuItemActionPerformed(evt);
            }
        });

        updateFeedsMenuItem.setText("Update Feeds");
        updateFeedsMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateFeedsMenuItemActionPerformed(evt);
            }
        });

        windowOpacityMenu.setText("Set Window Opacity");

        opacityRadioButtonGroup.add(fullOpacityButton);
        fullOpacityButton.setText("1.0");
        fullOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(fullOpacityButton);

        opacityRadioButtonGroup.add(nintyPercentOpacityButton);
        nintyPercentOpacityButton.setText("0.9");
        nintyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(nintyPercentOpacityButton);

        opacityRadioButtonGroup.add(eightyPercentOpacityButton);
        eightyPercentOpacityButton.setText("0.8");
        eightyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(eightyPercentOpacityButton);

        opacityRadioButtonGroup.add(seventyPercentOpacityButton);
        seventyPercentOpacityButton.setText("0.7");
        seventyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(seventyPercentOpacityButton);

        opacityRadioButtonGroup.add(sixtyPercentOpacityButton);
        sixtyPercentOpacityButton.setText("0.6");
        sixtyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(sixtyPercentOpacityButton);

        opacityRadioButtonGroup.add(fiftyPercentOpacityButton);
        fiftyPercentOpacityButton.setText("0.5");
        fiftyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(fiftyPercentOpacityButton);

        opacityRadioButtonGroup.add(fortyPercentOpacityButton);
        fortyPercentOpacityButton.setText("0.4");
        fortyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(fortyPercentOpacityButton);

        opacityRadioButtonGroup.add(thirtyPercentOpacityButton);
        thirtyPercentOpacityButton.setText("0.3");
        thirtyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(thirtyPercentOpacityButton);

        opacityRadioButtonGroup.add(twentyPercentOpacityButton);
        twentyPercentOpacityButton.setText("0.2");
        twentyPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(twentyPercentOpacityButton);

        opacityRadioButtonGroup.add(tenPercentOpacityButton);
        tenPercentOpacityButton.setText("0.1");
        tenPercentOpacityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                opacityButtonsActionPerformed(evt);
            }
        });
        windowOpacityMenu.add(tenPercentOpacityButton);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setUndecorated(true);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                formComponentShown(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
        });

        RssReaderPanel.setOpaque(false);

        FeedsPanel.setOpaque(false);

        FeedsScrollPane.setOpaque(false);

        feedsDisplayList.setModel(rssReaderListModel);
        feedsDisplayList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        feedsDisplayList.setToolTipText("Double click to view site");
        feedsDisplayList.setFocusable(false);
        feedsDisplayList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
        feedsDisplayList.setOpaque(false);
        feedsDisplayList.setSelectionBackground(new java.awt.Color(255, 255, 255));
        feedsDisplayList.setVisibleRowCount(1);
        feedsDisplayList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                feedsDisplayListMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                feedsDisplayListMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                feedsDisplayListMouseReleased(evt);
            }
        });
        feedsDisplayList.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                feedsDisplayListMouseDragged(evt);
            }
        });
        FeedsScrollPane.setViewportView(feedsDisplayList);

        javax.swing.GroupLayout FeedsPanelLayout = new javax.swing.GroupLayout(FeedsPanel);
        FeedsPanel.setLayout(FeedsPanelLayout);
        FeedsPanelLayout.setHorizontalGroup(
            FeedsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(FeedsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 988, Short.MAX_VALUE)
        );
        FeedsPanelLayout.setVerticalGroup(
            FeedsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(FeedsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout RssReaderPanelLayout = new javax.swing.GroupLayout(RssReaderPanel);
        RssReaderPanel.setLayout(RssReaderPanelLayout);
        RssReaderPanelLayout.setHorizontalGroup(
            RssReaderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(FeedsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        RssReaderPanelLayout.setVerticalGroup(
            RssReaderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(FeedsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(RssReaderPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(RssReaderPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents


        

     /**
     * Event Listener to open rss url in default browser when clicked in rssReaderListModel.
     * 
     * @param awt.event.ActionEvent evt
     */
    private void feedsDisplayListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_feedsDisplayListMouseClicked
        
        Object source = evt.getSource();
        
        //Check make sure the list item was double clicked
        if ((source == feedsDisplayList) && (evt.getClickCount() == 2))
        {
            //Get the url from the ItemComponent and desplay the page in syatem default browser
            String url = feedsDisplayList.getSelectedValue().getItemURL();
            openDefaultBrowser(url);
        }
    }//GEN-LAST:event_feedsDisplayListMouseClicked
    
    
     /**
     * Event Listener to create showInputDialog and to add an rssFeed to the database and displaylist
     * 
     * @param awt.event.ActionEvent evt
     */
    private void addRssMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addRssMenuItemActionPerformed

        //Show a window asking for a url to the rss feed
        String url = (String)JOptionPane.showInputDialog(null, "Enter Rss Feed URL",
                                                         "Add Rss Feed", JOptionPane.PLAIN_MESSAGE,
                                                          new ImageIcon(), null,
                                                          "paste link here");
        //if user hits cancel do nothing. 
        if(url == null){
           return;}
        //check if allready added
        if(!rssFeedsDB.containsFeedWithURL(url))
        {
                //Add the feed
            try{
                //Create the rssFeed and catch exceptions
                RssFeed rssFeed = RssFeedFactory.createRssFeed(url);

                //Add rss feed to database
                rssFeedsDB.addRssFeed(rssFeed);

                //Add the feed to the list;
                addRssFeedToDisplayList(rssFeed);

            } catch (Exception ex) {

                String errorMessage = "";

                //If the user entered a bad url create custom measage
                //otherwise provide defalt error message
                if(ex instanceof MalformedURLException){

                    errorMessage = "Feed could not be added. The provided Url is malformed.";}
                else{
                    errorMessage = "Error: Feed could not be added.";}

                //Show the message containing the error information.
                JOptionPane.showMessageDialog(null, errorMessage);
            }
        }
        else
        {
            JOptionPane.showMessageDialog(null, "The Rss Feed is all ready added");  
        }

    }//GEN-LAST:event_addRssMenuItemActionPerformed

    
     /**
     * Event Listener sets the opacity of RssReaderFrame when user selects opacity buttons
     * 
     * @param awt.event.ActionEvent evt
     */
    private void opacityButtonsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_opacityButtonsActionPerformed
        this.setOpacity(Float.parseFloat(evt.getActionCommand()));
        
    }//GEN-LAST:event_opacityButtonsActionPerformed
     /**
     * Event listener Method saves the RssFeeds database on window closing event
     * 
     * @param awt.event.WindowEvent evt
     */
    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        //Save the rssFeedsDB
        try {
            rssFeedsDB.saveDB();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_formWindowClosing
    
     /**
     * Event listener opens inputdialog to prompt user for an RssFeed to remove. Then 
     * removes the rss feed.
     * 
     * @param awt.event.ActionEvent evt
     */
    private void removeRssMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeRssMenuItemActionPerformed
        //checks that there are feeds in the first place
        if(!rssFeedsDB.isEmpty())
        {     
        //Show a window with a list of current rss feeds and ask with one to remeove
        String title = (String)JOptionPane.showInputDialog(null, "Choose a feed to remove from the list",
                                                         "Remove Rss Feed", JOptionPane.PLAIN_MESSAGE,
                                                          new ImageIcon(), 
                                                          rssFeedsDB.getAllFeedTitles().toArray(),
                                                          null);
            //Use returned string title to delete feed from database
            if(rssFeedsDB.removeRssFeedByTitle(title))
            {
                //Update the display list model if the remove was a success
                updateDisplayListModel(rssFeedsDB.getFeedsIterator());
            }else
            {
                   JOptionPane.showMessageDialog(null, "The feed couldn't be removed");  
            }

        }
        else
        {
            JOptionPane.showMessageDialog(null, "There are no feeds to remove");  
        }
    }//GEN-LAST:event_removeRssMenuItemActionPerformed

     /**
     * Method calls {@link updateRssFeeds} method
     * 
     * @param awt.event.ActionEvent evt
     */
    private void updateFeedsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateFeedsMenuItemActionPerformed
        updateRssFeeds();
    }//GEN-LAST:event_updateFeedsMenuItemActionPerformed

    private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
        Point pnt = evt.getLocationOnScreen();
        String pInfo = "x = " + String.valueOf(pnt.x) + " y = " + String.valueOf(pnt.y);
        super.setLocation(pnt);
        //JOptionPane.showConfirmDialog(this, pInfo);
    }//GEN-LAST:event_formMouseDragged

    private void feedsDisplayListMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_feedsDisplayListMouseDragged
        Point mosPnt = evt.getLocationOnScreen();
        Point winPnt = super.getLocationOnScreen();
        String pInfo = "x = " + String.valueOf(mosPnt.x) + " y = " + String.valueOf(mosPnt.y);
        
        super.setLocation(mosPnt);
        //JOptionPane.showConfirmDialog(this, pInfo);
    }//GEN-LAST:event_feedsDisplayListMouseDragged

    private void feedsDisplayListMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_feedsDisplayListMousePressed
        if(evt.isPopupTrigger())
        {
          JPopupMenu jPopupMenu = new JPopupMenu();
          jPopupMenu.add(addRssMenuItem);
          jPopupMenu.add(removeRssMenuItem);
          jPopupMenu.add(windowOpacityMenu);
          jPopupMenu.add(updateFeedsMenuItem);
          jPopupMenu.add(exitMenuItem);

          
          jPopupMenu.show(evt.getComponent(),evt.getX(), evt.getY());
        }
    }//GEN-LAST:event_feedsDisplayListMousePressed

    private void feedsDisplayListMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_feedsDisplayListMouseReleased
        if(evt.isPopupTrigger())
        {
          JPopupMenu jPopupMenu = new JPopupMenu();
          jPopupMenu.add(addRssMenuItem);
          jPopupMenu.add(removeRssMenuItem);
          jPopupMenu.add(windowOpacityMenu);
          jPopupMenu.add(updateFeedsMenuItem);
          jPopupMenu.add(exitMenuItem);

          
          jPopupMenu.show(evt.getComponent(),evt.getX(), evt.getY());
        }
    }//GEN-LAST:event_feedsDisplayListMouseReleased

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
     super.getToolkit().getSystemEventQueue().postEvent(new WindowEvent(this,WindowEvent.WINDOW_CLOSING));
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
        //Start timer for animation
        scrollAnimationTimer.start();
        updateFeedsTimer.start();
    }//GEN-LAST:event_formComponentShown


    
    
    
    /**
     * Method to add an RssFeeds components to the rssReaderListModel
     * 
     * @param an {@link RssFeed}RssFeed object
     */
    private void addRssFeedToDisplayList(RssFeed rssFeed)
  {
      //Get iterator to RssFeeds components.
      Iterator<ItemComponent> itemIterator = rssFeed.getFeedComponentsIterator();
      //Add each component to the list. 
      while(itemIterator.hasNext()){
      rssReaderListModel.insertElementAt(itemIterator.next(), rssReaderListModel.getSize());
      }
  }
  

    
    /**
     * method Centers main window
     */
    private void centerWindow()
      {
        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension d = tk.getScreenSize();
        this.setLocation((d.width-this.getWidth())/2, (d.height-this.getHeight())/2);
      }
      
      
     /**
     * Method to follow a string url in the systems default browser 
     * 
     * @param a String containing a url
     */
      private void openDefaultBrowser(String url)
      {
            java.net.URI uri = null;
            try {
                uri = new java.net.URI(url);
            } catch (URISyntaxException ex) {
                Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                java.awt.Desktop.getDesktop().browse(uri);
            } catch (IOException ex) {
                Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
      }
      
      
      /**
       * Method clears all RssFeeds in the displayListModel and uses the param
       * iterator in the {@link RssFeedsDB}s to create a new RssFeed list.
       * 
       * @param iterator
       */
      private void updateDisplayListModel(Iterator<RssFeed> iterator)
      {
          rssReaderListModel.clear();
          while(iterator.hasNext()){
              addRssFeedToDisplayList(iterator.next());
          }                  
      }
      
      
      /**
       * Method to update all the data in the rssFeeds in the rssFeedsDB
       */
      private void updateRssFeeds()
      {
        //get an iterator into the database and create an arraylist to hold updated feeds
        Iterator<RssFeed> feedsIterator = rssFeedsDB.getFeedsIterator();
        ArrayList<RssFeed> updatedFeeds = new ArrayList<>(0);
        
        //iterate throught database and check if rssfeed needs to be updated
        while(feedsIterator.hasNext())
        {
            //Get the last modified date from the rssfeed url header
            RssFeed rssFeed = feedsIterator.next();
            String currentLastModifiedDate = rssFeed.getLastModified();
            String actualLastModifiedDate = RssFeedFactory.getRssFeedLastModifiedDate(rssFeed);
            
            //if the current mod date doesnt match our old one then update
            if(!currentLastModifiedDate.equals(actualLastModifiedDate))
            {
                //Create a new RssFeed object from the old ones url 
                //and add it to our updated feeds arraylist
                RssFeed updatedRssFeed;
                try {
                    updatedRssFeed = RssFeedFactory.createRssFeed(rssFeed.getRssURL());
                    updatedFeeds.add(updatedRssFeed);
                } catch (Exception ex) {
                    Logger.getLogger(RssReaderFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
                //remove the outdated rss feed
                feedsIterator.remove();
            }
        }
        
        //Add the updated RssFeeds to the rssFeedsDB if there are any
        if(!updatedFeeds.isEmpty())
        {
            //Add them to the DB
            for(RssFeed updatedFeed: updatedFeeds)
            {
                rssFeedsDB.addRssFeed(updatedFeed);
            }
            //Update the gui
            updateDisplayListModel(rssFeedsDB.getFeedsIterator());
        }
      }
      

    //Variables Declarations
    final int HOUR   = 3600000;
    final int MINUTE = 60000;
    final int SECOND = 6000;
      
    private DefaultListModel<ItemComponent> rssReaderListModel = new DefaultListModel();
    RssFeedsDB rssFeedsDB;
    Timer scrollAnimationTimer;
    Timer updateFeedsTimer;
    JViewport viewport;
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel FeedsPanel;
    private javax.swing.JScrollPane FeedsScrollPane;
    private javax.swing.JPanel RssReaderPanel;
    private javax.swing.JMenuItem addRssMenuItem;
    private javax.swing.JRadioButtonMenuItem eightyPercentOpacityButton;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JList<rssreaderapp.ItemComponent> feedsDisplayList;
    private javax.swing.JRadioButtonMenuItem fiftyPercentOpacityButton;
    private javax.swing.JRadioButtonMenuItem fortyPercentOpacityButton;
    private javax.swing.JRadioButtonMenuItem fullOpacityButton;
    private javax.swing.JRadioButtonMenuItem nintyPercentOpacityButton;
    private javax.swing.ButtonGroup opacityRadioButtonGroup;
    private javax.swing.JMenuItem removeRssMenuItem;
    private javax.swing.JRadioButtonMenuItem seventyPercentOpacityButton;
    private javax.swing.JRadioButtonMenuItem sixtyPercentOpacityButton;
    private javax.swing.JRadioButtonMenuItem tenPercentOpacityButton;
    private javax.swing.JRadioButtonMenuItem thirtyPercentOpacityButton;
    private javax.swing.JRadioButtonMenuItem twentyPercentOpacityButton;
    private javax.swing.JMenuItem updateFeedsMenuItem;
    private javax.swing.JMenu windowOpacityMenu;
    // End of variables declaration//GEN-END:variables
      
 
}
